﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Infrastructure.ObjectModel;
using Microsoft.Xna.Framework;
using B10_Ex02_Elad_034695114_Meyron_026607788;

namespace B10_Ex02_EladLebovitch_034695114.ObjectModel
{
    public class GameStatusDisplay : LoadableDrawableComponent
    {
        #region Consts
        private const string k_assetName = @"Fonts\ScoreFont";
        private const string k_TextStart = @"P";
        private const string k_TextEnd = @" Score:";
        private const int k_halfOpacitit = 123;
        private const int k_fontSize = 25;
        private const int k_fontOffset = 5;
        #endregion

        #region Data members
        protected SpriteBatch m_SpriteBatch;
        private bool m_UseSharedBatch = true;
        private bool m_didScoreOrLivesChanged = true;
        private SpriteFont m_spfScoreFont;
        private string m_strScoreBoard1 = "";
        private string m_strScoreBoard2 = "";
        private HumanPlayer m_humPlayerOne;
        private HumanPlayer m_humPlayerTwo;

        private Color PlayerOneColor
        {
            get;
            set;
        }

        private Color PlayerTwoColor
        {
            get;
            set;
        } 
        #endregion

        #region Ctor and Other methods
        /// <summary>
        /// Creates a game status display
        /// </summary>
        /// <param name="i_Game"></param>
        /// <param name="i_humPlayerOne"></param>
        /// <param name="i_humPlayerTwo"></param>
        /// <param name="i_PlayerOneColor"></param>
        /// <param name="i_PlayerTwoColor"></param>
        public GameStatusDisplay(Game i_Game, HumanPlayer i_humPlayerOne, HumanPlayer i_humPlayerTwo,
                                 Color i_PlayerOneColor, Color i_PlayerTwoColor)
            : base(k_assetName, i_Game, 0)
        {
            // Register component
            this.Game.Components.Add(this);
            this.Enabled = true;
            this.Visible = true;

            // Draw after background
            this.DrawOrder = 2;

            // Save these players
            m_humPlayerOne = i_humPlayerOne;
            m_humPlayerTwo = i_humPlayerTwo;
            PlayerOneColor = i_PlayerOneColor;
            PlayerTwoColor = i_PlayerTwoColor;

            // Register to events
            m_humPlayerOne.PlayerShip.PlayerShipDestroyedEvent += new PlayerShipDestroyed(PlayerShipDestroyed);
            m_humPlayerOne.PlayerScoreChangedEvent += new EventHandler(ScoreChanged);
            m_humPlayerTwo.PlayerScoreChangedEvent += new EventHandler(ScoreChanged);
            m_humPlayerTwo.PlayerShip.PlayerShipDestroyedEvent += new PlayerShipDestroyed(PlayerShipDestroyed);
        }

        /// <summary>
        /// If a ship is destroyed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void PlayerShipDestroyed(object sender, EventArgs e)
        {
            m_didScoreOrLivesChanged = true;
        }

        /// <summary>
        /// If score has changed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void ScoreChanged(object sender, EventArgs e)
        {
            m_didScoreOrLivesChanged = true;
        }

        /// <summary>
        /// Refreshes text for both players
        /// </summary>
        private void refreshText()
        {
            // Set the new score
            m_strScoreBoard1 = GetTextForPlayer(m_humPlayerOne);
            m_strScoreBoard2 = GetTextForPlayer(m_humPlayerTwo);
        }

        /// <summary>
        /// Sets text for player
        /// </summary>
        /// <param name="i_curPlayer"></param>
        /// <returns></returns>
        private string GetTextForPlayer(HumanPlayer i_curPlayer)
        {
            // Set the text
            return (k_TextStart + i_curPlayer.PlayerNumber + k_TextEnd + i_curPlayer.GameScore.ToString());
        }

        protected override void InitBounds()
        {
            // not implemented
        }

        protected override void DrawBoundingBox()
        {
            // not implemented
        }

        /// <summary>
        /// Loads the sprite font
        /// </summary>
        protected override void LoadContent()
        {
            // Load the sprite font
            m_spfScoreFont = Game.Content.Load<SpriteFont>(k_assetName);

            // Check the sprite batch
            if (m_SpriteBatch == null)
            {
                // maybe needed to refresh
                m_SpriteBatch =
                    Game.Services.GetService(typeof(SpriteBatch)) as SpriteBatch;

                // maybe needed to refresh
                if (m_SpriteBatch == null)
                {
                    m_SpriteBatch = new SpriteBatch(Game.GraphicsDevice);
                }
            }
            base.LoadContent();
        }

        /// <summary>
        /// Resets the data for display
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Update(GameTime gameTime)
        {
            // Update text if somthing changed
            if (m_didScoreOrLivesChanged)
            {
                refreshText();
            }
            base.Update(gameTime);
        }

        /// <summary>
        /// Draws the data
        /// </summary>
        /// <param name="i_humPlayer"></param>
        private void drawPlayerData(HumanPlayer i_humPlayer)
        {
            // Get the texture for the ship
            Texture2D txtShip = i_humPlayer.PlayerShip.Texture;

            // Draw the space ship a couple of times
            for (int i = 1; i <= i_humPlayer.Souls; i++)
            {
                // Draw it half the size, and a little 
                m_SpriteBatch.Draw(txtShip, new Rectangle(Game.GraphicsDevice.Viewport.Width -
                                                          (txtShip.Width / 2) * i, ((txtShip.Height) * (i_humPlayer.PlayerNumber - 1)), txtShip.Width / 2, txtShip.Height / 2), new Color(Color.White, k_halfOpacitit));

            }
        }

        /// <summary>
        /// Normal draw
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Draw(GameTime gameTime)
        {
            if (!m_UseSharedBatch)
            {
                m_SpriteBatch.Begin();
            }

            // Draw the text
            m_SpriteBatch.DrawString(m_spfScoreFont, m_strScoreBoard1, new Vector2(k_fontOffset, (m_humPlayerOne.PlayerNumber - 1) * k_fontSize), PlayerOneColor);
            m_SpriteBatch.DrawString(m_spfScoreFont, m_strScoreBoard2, new Vector2(k_fontOffset, (m_humPlayerTwo.PlayerNumber - 1) * k_fontSize), PlayerTwoColor);
            drawPlayerData(m_humPlayerOne);
            drawPlayerData(m_humPlayerTwo);

            if (!m_UseSharedBatch)
            {
                m_SpriteBatch.End();
            }

            base.Draw(gameTime);
        } 
        #endregion
    }
}